package com.awanp3.nimbus.common.websocket.controller;

import com.awanp3.nimbus.common.core.domain.R;
import com.awanp3.nimbus.common.core.utils.SpringUtils;
import com.awanp3.nimbus.common.websocket.dto.WebSocketMessageDto;
import com.awanp3.nimbus.common.websocket.holder.WebSocketSessionHolder;
import com.awanp3.nimbus.common.websocket.utils.WebSocketUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;

/**
 * Websocket 控制器
 *
 * @author 20014170
 */
@Slf4j
@RestController
@ConditionalOnProperty(value = "websocket.enabled", havingValue = "true")
@RequiredArgsConstructor
public class WebsocketController implements DisposableBean {


    /**
     * 向特定用户发送消息
     *
     * @param userId 目标用户的 ID
     * @param message    要发送的消息内容
     */
    @GetMapping(value = "${websocket.path}/send")
    public R<Void> send(Long userId, String message) {
        WebSocketUtils.sendMessage(userId, message);
        return R.ok();
    }

    /**
     * 向特定用户发送消息
     *
     * @param message    要发送的消息内容
     */
    @GetMapping(value = "${websocket.path}/sendAll")
    public R<Void> sendAll(String message) {
        WebSocketUtils.sendMessage(message);
        return R.ok();
    }

    /**
     * 向所有用户发送消息
     *
     * @param topic 要发送的消息内容
     */
    @GetMapping(value = "${websocket.path}/subscribe")
    public R<Void> subscribe(String topic) {
        WebSocketUtils.subscribeMessage(topic, message -> {
            WebSocketSessionHolder.getSessionsAll().forEach(key -> {
                WebSocketUtils.sendMessage(key, message.getMessage());
            });
        });
        return R.ok();
    }

    /**
     * 向所有用户发送消息
     *
     * @param message 要发送的消息内容
     */
    @GetMapping(value = "${websocket.path}/publish")
    public R<Void> publish(String topic, Long[] userIds, String message) {
        WebSocketMessageDto webSocketMessageDto = new WebSocketMessageDto();
        webSocketMessageDto.setSessionKeys(Arrays.asList(userIds));
        webSocketMessageDto.setMessage(message);
        WebSocketUtils.publishMessage(topic, webSocketMessageDto);
        return R.ok();
    }

    /**
     * 向所有用户发送消息
     *
     * @param topic   发送主题
     * @param message 要发送的消息内容
     */
    @GetMapping(value = "${websocket.path}/publishAll")
    public R<Void> publish(String topic, String message) {
        WebSocketUtils.publishAll(topic, message);
        return R.ok();
    }

    /**
     * 查看是否允许使用Websocket
     */
    @GetMapping(value = "${websocket.path}/getEnabled")
    public R<Boolean> getEnabled() {
        return R.ok(SpringUtils.getProperty("websocket.enabled", Boolean.class, false));
    }

    /**
     * 清理资源。此方法目前不执行任何操作，但避免因未实现而导致错误
     */
    @Override
    public void destroy() throws Exception {
        // 销毁时不需要做什么 此方法避免无用操作报错
    }

}
